package spring.aop.jdkproxy;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author GY
 * @date 2019年1月19日
 * @说明: 内存中动态生成的代理类的猜想
 */
public class MyIServiceProxy extends Proxy implements IService {
    private static final long serialVersionUID = 1L;
    protected MyIServiceProxy(InvocationHandler h) {
        super(h);
    }
    @Override
    public String say(int i) {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StackTraceElement m1Stack = stackTrace[1];
        String currentMethodName = m1Stack.getMethodName();
        try {
            return (String) h.invoke(this, IService.class.getMethod(currentMethodName, new Class[] { int.class }), new Object[] {i});
//            return (String) h.invoke(getFieldValueByClass(h, IService.class), 
//                    IService.class.getMethod(currentMethodName, new Class[] { int.class }), new Object[] {i});
        } catch (Throwable e) {
            e.printStackTrace();
            throw new UndeclaredThrowableException(e);
        }
    }
    public Object getFieldValueByClass(Object obj, Class<?> fieldCls) {
        System.out.println(h.getClass());
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName());
            field.setAccessible(true);
            if(field.getType() != Object.class) continue;
            Object object = null;
            try {
                object = field.get(obj);
            } catch (IllegalArgumentException | IllegalAccessException e1) {
                e1.printStackTrace();
            }
            if(object != null && fieldCls.isAssignableFrom(object.getClass())) {
                return object;
            }
        }
        throw new RuntimeException("获取h中的被代理对象target异常");
    }
}
